package com.atguigu.gulimall.product.service.impl;

import com.atguigu.common.constant.ProductConstant;
import com.atguigu.common.to.es.SkuEsModel;
import com.atguigu.common.to.es.SkuHasStockVo;
import com.atguigu.common.utils.R;
import com.atguigu.gulimall.product.entity.*;
import com.atguigu.gulimall.product.feign.SearchFeignService;
import com.atguigu.gulimall.product.feign.WareFeginService;
import com.atguigu.gulimall.product.service.*;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.atguigu.common.utils.PageUtils;
import com.atguigu.common.utils.Query;

import com.atguigu.gulimall.product.dao.SpuInfoDao;

import javax.annotation.Resource;


@Service("spuInfoService")
public class SpuInfoServiceImpl extends ServiceImpl<SpuInfoDao, SpuInfoEntity> implements SpuInfoService {

	@Autowired
	private SkuInfoService skuInfoService;

	@Autowired
	private BrandService brandService;

	@Autowired
	private CategoryService categoryService;

	@Autowired
	private ProductAttrValueService productAttrValueService;

	@Autowired
	private AttrService attrService;

	@Autowired
	SearchFeignService searchFeignService;     //远程调用Es存储服务

	@Autowired
	private WareFeginService wareFeginService;


	@Override
	public PageUtils queryPage(Map<String, Object> params) {
		IPage<SpuInfoEntity> page = this.page(
				new Query<SpuInfoEntity>().getPage(params),
				new QueryWrapper<SpuInfoEntity>()
		);

		return new PageUtils(page);
	}

	@Override
	public void up(Long spuId) throws IOException {

		// 1、查出当前spuid对应的所有sku信息，品牌名字
		List<SkuInfoEntity> skus = skuInfoService.getSkusBySpuId(spuId);

		//TODO 查询当前SKU可以被用来检索的规格属性
		List<ProductAttrValueEntity> baseAttrlistforspuId = productAttrValueService.baseAttrlistforspuId(spuId);

		//提取skuID
		List<Long> skuList = skus.stream().map(item -> {
			return item.getSkuId();
		}).collect(Collectors.toList());

		List<Long> arrtID = baseAttrlistforspuId.stream().map(pro -> {
			return pro.getAttrId();
		}).collect(Collectors.toList());

		List<Long> attrId = attrService.selectAttrById(arrtID);

		Set<Long> idSets = new HashSet<>(arrtID);

		List<SkuEsModel.Attr> attrList = baseAttrlistforspuId.stream().filter(item -> {
			return attrId.contains(item.getAttrId());
		}).map(item -> {
			SkuEsModel.Attr attr = new SkuEsModel.Attr();
			BeanUtils.copyProperties(item, attr);
			return attr;
		}).collect(Collectors.toList());

		//TODO 发送远程调用，查看是否有库存
		Map<Long, Boolean> stockMap = null;
		try {
			R<List<SkuHasStockVo>> skusHasStock = wareFeginService.getSkusHasStock(skuList);
			List<SkuHasStockVo> data = skusHasStock.getData();
			stockMap = data.stream().collect(Collectors.toMap(SkuHasStockVo::getSkuId, item -> item.getHasStock()));
		} catch (Exception e) {
			log.error("库存查询远程调用失败，{}", e);
		}
		// 2、组装每个Sku的信息
		Map<Long, Boolean> finalStockMap = stockMap;
		List<SkuEsModel> upProducts = skus.stream().map(sku -> {
			// 组装需要的数据
			SkuEsModel skuEsModel = new SkuEsModel();
			BeanUtils.copyProperties(sku, skuEsModel);

			skuEsModel.setSkuPrice(sku.getPrice());
			skuEsModel.setSkuImg(sku.getSkuDefaultImg());
			//设置是否有库存
			if (finalStockMap == null) {
				skuEsModel.setHasStock(true);
			} else {
				skuEsModel.setHasStock(finalStockMap.get(sku.getSkuId()));
			}

			//TODO 热度评分 0
			skuEsModel.setHotScore(0L);

			//TODO 查询品牌和分类的名字信息
			BrandEntity brandEntity = brandService.getById(skuEsModel.getBrandId());
			skuEsModel.setBrandName(brandEntity.getName());
			skuEsModel.setBrandImg(brandEntity.getLogo());

			CategoryEntity categoryEntity = categoryService.getById(skuEsModel.getCatalogId());
			skuEsModel.setCatalogName(categoryEntity.getName());

			skuEsModel.setAttrs(attrList);

			return skuEsModel;
		}).collect(Collectors.toList());

		// TODO 将数据发送给es进行保存；gulimall-search

		R r = searchFeignService.getSkuEsmodel(upProducts);

		if (r.getCode() == 0) {
			//远程调用成功
			//TODO 修改当前spu状态
			baseMapper.updateSpuStatus(spuId, ProductConstant.StatusEnum.SPU_UP.getCode());
		} else {
			//调用失败
			//TODO 重复调用，接口幂等性：重试机制



		}
	}
}